<chapter xml:id="bits.h">
<title><tt>__vic/bits.h</tt></title>

<p>Инструменты для манипуляции битами и байтами.</p>


<chapter xml:id="lo_nibble">
<title><tt>lo_nibble()</tt>, <tt>hi_nibble()</tt></title>

<code-block lang="C++">
constexpr uint8_t lo_nibble(uint8_t byte);
constexpr uint8_t hi_nibble(uint8_t byte);
</code-block>

<p>Возвращают значение младшего/старшего полубайта (тетрады), соответственно.
</p>

</chapter>


<chapter xml:id="msb_ones">
<title><tt>msb_ones()</tt>, <tt>lsb_ones()</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> constexpr T lsb_ones(unsigned bits_num);
template<class T> constexpr T msb_ones(unsigned bits_num);
]]></code-block>

<p>Возвращают значение типа <tt>T</tt> со всеми младшими/старшими
<tt>bits_num</tt> битами заполненными <tt>1</tt>, соответственно. Все остальные
биты установлены в <tt>0</tt>.</p>

</chapter>


<chapter xml:id="get_lsbs">
<title><tt>get_lsbs()</tt></title>

<code-block lang="C++">
template&lt;class T> constexpr T get_lsbs(T v, unsigned bits_num);
</code-block>

<p>Возвращает <tt>bits_num</tt> младших битов значения <tt>v</tt>. Другими
словами, заполняет нулями все, кроме младших <tt>bits_num</tt> битов.</p>

</chapter>


<chapter xml:id="ord">
<title><tt>ord()</tt></title>

<code-block lang="C++">
constexpr int ord(char ch);
</code-block>

<p>Возвращает код символа от 0 до 255.</p>
<postcondition>ord(ch) >= 0</postcondition>

</chapter>


<chapter xml:id="popcount">
<title><tt>popcount()</tt></title>

<code-block lang="C++">
unsigned popcount(unsigned v);
unsigned popcount(unsigned long v);
unsigned popcount(unsigned long long v);
unsigned popcount(unsigned short v);
unsigned popcount(unsigned char v);
</code-block>

<p>Возвращает количество единичных битов в данном значении.</p>

</chapter>


<chapter xml:id="msb_position">
<title><tt>msb_position()</tt></title>

<code-block lang="C++">
unsigned msb_position(unsigned v)
unsigned msb_position(unsigned long v);
unsigned msb_position(unsigned long long v);
unsigned msb_position(unsigned short v);
unsigned msb_position(unsigned char v);
</code-block>

<precondition><tt>v != 0</tt></precondition>

<p>Возвращает позицию самого значимого единичного бита. Результат неопределён,
если <tt>v == 0</tt>.</p>

</chapter>


<chapter xml:id="ispow2">
<title><tt>ispow2()</tt></title>

<code-block lang="C++"><![CDATA[
template<class UInt>
bool ispow2(UInt n);
]]></code-block>

<precondition><tt>UInt</tt> - беззнаковый целый тип</precondition>

<p>Возвращает <tt>true</tt>, если <tt>n</tt> является целой степенью 2.</p>

</chapter>


<chapter xml:id="ceil2">
<title><tt>ceil2()</tt></title>

<code-block lang="C++"><![CDATA[
template<class UInt>
UInt ceil2(UInt n);
]]></code-block>

<precondition><tt>UInt</tt> - беззнаковый целый тип</precondition>

<p>Возвращает минимальное значение <tt>m</tt>, такое что <tt>ispow(m) &amp;&amp;
m >= n</tt>. Если <tt>m</tt> непредставимо типом <tt>UInt</tt>, результат
неопределён.</p>

</chapter>


<chapter xml:id="floor2">
<title><tt>floor2()</tt></title>

<code-block lang="C++"><![CDATA[
template<class UInt>
UInt floor2(UInt n);
]]></code-block>

<precondition><tt>UInt</tt> - беззнаковый целый тип</precondition>

<p>Если <tt>n != 0</tt>, возвращает максимальное значение <tt>m</tt>, такое что
<tt>ispow2(m) &amp;&amp; m &lt;= n</tt>. В противном случае возвращается
<tt>0</tt>.</p>

</chapter>


<chapter xml:id="ceil_log2">
<title><tt>ceil_log2()</tt></title>

<code-block lang="C++"><![CDATA[
template<class UInt>
unsigned ceil_log2(UInt n);
]]></code-block>

<precondition><tt>UInt</tt> - беззнаковый целый тип</precondition>

<p>Возвращает <tt>ceil(log2(n))</tt>, если <tt>n != 0</tt>, или 0 в
противном случае.</p>

</chapter>


<chapter xml:id="floor_log2">
<title><tt>floor_log2()</tt></title>

<code-block lang="C++"><![CDATA[
template<class UInt>
unsigned floor_log2(UInt n);
]]></code-block>

<precondition><tt>UInt</tt> - беззнаковый целый тип</precondition>

<p>Возвращает <tt>floor(log2(n))</tt>, если <tt>n != 0</tt>, или 0 в
противном случае.</p>

</chapter>


<chapter xml:id="rotl">
<title><tt>rotl()</tt>, <tt>rotr()</tt></title>

<code-block lang="C++">
unsigned long long rotl(unsigned long long v, int shift);
unsigned long      rotl(unsigned long v, int shift);
unsigned           rotl(unsigned v, int shift);
unsigned short     rotl(unsigned short v, int shift);
unsigned char      rotl(unsigned char v, int shift);

unsigned long long rotr(unsigned long long v, int shift);
unsigned long      rotr(unsigned long v, int shift);
unsigned           rotr(unsigned v, int shift);
unsigned short     rotr(unsigned short v, int shift);
unsigned char      rotr(unsigned char v, int shift);
</code-block>

<p>Функции выполняют циклический побитовый сдвиг (rotation) влево
(<tt>rotl</tt>) или вправо (<tt>rotr</tt>).</p>
<precondition><tt>0 &lt;= shift &amp;&amp; shift &lt; sizeof(v)*CHAR_BIT</tt></precondition>

</chapter>


<chapter xml:id="swapped_nibbles">
<title><tt>swapped_nibbles()</tt></title>

<code-block lang="C++">
constexpr uint8_t swapped_nibbles(uint8_t b);
</code-block>

<p>Меняет местами младший и старший полубайт значения и возвращает его.</p>

</chapter>


</chapter>
